home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_217 / stevie / amiga.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  9KB  |  434 lines

  1. /*
  2.  * Amiga system-dependent routines. 
  3.  */
  4.  
  5. #include <proto/exec.h>
  6. #include <proto/dos.h>
  7. #include <exec/memory.h>
  8. #include <devices/conunit.h>
  9. #include <stdio.h>
  10. #include <ios1.h>
  11. #include <error.h>
  12.  
  13. #include "stevie.h"
  14.  
  15. /* Globals initialized by get_ConUnit() */
  16. struct Window  *conWindow;
  17. struct ConUnit *conUnit;
  18.  
  19. extern int      errno;        /* The error variable */
  20.  
  21. long            raw_in = 0;
  22. long            raw_out = 0;
  23.  
  24. #define BSIZE   2048
  25. static char     outbuf[BSIZE];
  26. static int      bpos = 0;
  27.  
  28. void
  29. flushbuf()
  30. {
  31.     if (bpos != 0)
  32.     Write(raw_out, outbuf, bpos);
  33.     bpos = 0;
  34. }
  35.  
  36. void
  37. outchar(c)
  38.     char            c;
  39. {
  40.     outbuf[bpos++] = c;
  41.     if (bpos >= BSIZE)
  42.     flushbuf();
  43. }
  44.  
  45. void
  46. outstr(s)
  47.     char           *s;
  48. {
  49.     while (*s) {
  50.     outbuf[bpos++] = *s++;
  51.     if (bpos >= BSIZE)
  52.         flushbuf();
  53.     }
  54. }
  55.  
  56. int
  57. GetCharacter()
  58. {
  59.     char            c;
  60.  
  61.     Read(raw_in, &c, sizeof(c));
  62.     return ((int) c);
  63. }
  64.  
  65. /*
  66.  * getCSIsequence - get a CSI sequence
  67.  *                - either cursor keys, help, or function keys
  68.  */
  69.  
  70. int
  71. getCSIsequence()
  72. {
  73.     int             c;
  74.     int             tmp;
  75.  
  76.  
  77.     c = GetCharacter();
  78.     if (isdigit(c)) {
  79.     tmp = 0;
  80.     while (isdigit(c)) {
  81.         tmp = tmp * 10 + c - '0';
  82.         c = GetCharacter();
  83.     }
  84.     if (c == '~')        /* function key */
  85.         return ((char) (K_F1 + tmp));
  86.     }
  87.     switch (c) {
  88.       case 'A':        /* cursor up */
  89.     return K_UARROW;
  90.       case 'B':        /* cursor down */
  91.     return K_DARROW;
  92.       case 'C':        /* cursor right */
  93.     return K_RARROW;
  94.       case 'D':        /* cursor left */
  95.     return K_LARROW;
  96.       case 'T':        /* shift cursor up */
  97.     return K_SUARROW;
  98.       case 'S':        /* shift cursor down */
  99.     return K_SDARROW;
  100.       case ' ':        /* shift cursor left or right */
  101.     c = GetCharacter();
  102.     if (c == 'A')        /* shift cursor left */
  103.         return K_SLARROW;
  104.     if (c == '@')        /* shift cursor right */
  105.         return K_SRARROW;
  106.     break;
  107.       case '?':        /* help */
  108.     c = GetCharacter();
  109.     if (c == '~')
  110.         return K_HELP;
  111.     break;
  112.     }
  113.     while ((c != '|') && (c != '~')) {
  114.     if (WaitForChar(raw_in, 500L) == 0)
  115.         break;
  116.     c = GetCharacter();
  117.     }
  118.  
  119.     /* must have been screen resize event */
  120.     s_clear();
  121.     flushbuf();
  122.     if (get_ConUnit(raw_in) != 0) {    /* hopefully never exit .... */
  123.     emsg("STEVIE: can't get ConUnit info ?!?!?!?\n");
  124.     sleep(5);
  125.     return 0;
  126.     }
  127.     Rows = conUnit->cu_YMax + 1;
  128.     Columns = conUnit->cu_XMax + 1;
  129.     if (Columns < 5)
  130.     Columns = 5;
  131.     if (Columns > MAX_COLUMNS)
  132.     Columns = MAX_COLUMNS;
  133.     if (Rows < 2)
  134.     Rows = 2;
  135.     P(P_LI) = Rows;
  136.  
  137.     screenalloc();
  138.     tmp = RedrawingDisabled;
  139.     RedrawingDisabled = TRUE;
  140.     S_NOT_VALID;
  141.     cursupdate(UPDATE_ALL);    /* make sure not below Botchar */
  142.     RedrawingDisabled = FALSE;
  143.     s_refresh(NOT_VALID);    /* draw it */
  144.     RedrawingDisabled = tmp;
  145.     windgoto(Cursrow, Curscol);
  146.     flushbuf();
  147.  
  148.     return 0;
  149. }
  150.  
  151. /*
  152.  * inchar() - get a character from the keyboard 
  153.  */
  154. int
  155. inchar()
  156. {
  157.     int             c;
  158.  
  159.     flushbuf();
  160.  
  161.     for (;;) {
  162.     c = GetCharacter();
  163.     if (c == 0x9b)
  164.         c = getCSIsequence();
  165.     if (c != 0)
  166.         break;
  167.     }
  168.  
  169.     return c;
  170. }
  171.  
  172. void
  173. beep()
  174. {
  175.     if (RedrawingDisabled)
  176.     return;
  177.  
  178.     outbuf[bpos++] = '\007';
  179.     if (bpos >= BSIZE)
  180.     flushbuf();
  181. }
  182.  
  183. void
  184. sleep(n)
  185.     int             n;
  186. {
  187.     void            Delay();
  188.  
  189.     if (n > 0)
  190.     Delay(50L * n);
  191. }
  192.  
  193. void
  194. delay()
  195. {
  196.     void            Delay();
  197.  
  198.     Delay(25L);
  199. }
  200.  
  201. void
  202. windinit()
  203. {
  204.     raw_in = Input();
  205.     if (!IsInteractive(raw_in)) {
  206.     raw_in = Open("RAW:0/0/480/200/STEVIE", MODE_NEWFILE);
  207.     if (raw_in == NULL) {
  208.         fprintf(stderr, "STEVIE: Can't open window ?!?!?!?\n");
  209.         exit(2);
  210.     }
  211.     raw_out = raw_in;
  212.     } else {
  213.     raw_out = Output();
  214.     if (raw(raw_in) != 0) {
  215.         perror("STEVIE: Can't change to raw mode ?!?!?!?");
  216.         exit(2);
  217.     }
  218.     }
  219.  
  220.     if (get_ConUnit(raw_in) != 0) {
  221.     fprintf(stderr, "STEVIE: can't get ConUnit info ?!?!?!?\n");
  222.     windexit(3);
  223.     }
  224.     /* get window size */
  225.     P(P_LI) = Rows = conUnit->cu_YMax + 1;
  226.     Columns = conUnit->cu_XMax + 1;
  227.  
  228.     outstr("\033[12{");        /* window resize events activated */
  229.     flushbuf();
  230. }
  231.  
  232. void
  233. windexit(r)
  234.     int             r;
  235. {
  236.     outstr("\033[12}");        /* window resize events de-activated */
  237.     flushbuf();
  238.  
  239.     if (raw_in != raw_out) {
  240.     if (cooked(raw_in) != 0)
  241.         perror("STEVIE: Can't change to cooked mode ?!?!?!?");
  242.     } else {
  243.     Close(raw_in);
  244.     }
  245.  
  246.     exit(r);
  247. }
  248.  
  249. void
  250. windgoto(r, c)
  251.     int             c;
  252.     int             r;
  253. {
  254.     r++;
  255.     c++;
  256.  
  257.     outstr("\033[");
  258.     if (r >= 10)
  259.     outchar((char) (r / 10 + '0'));
  260.     outchar((char) (r % 10 + '0'));
  261.     outchar(';');
  262.     if (c >= 10)
  263.     outchar((char) (c / 10 + '0'));
  264.     outchar((char) (c % 10 + '0'));
  265.     outchar('H');
  266. }
  267.  
  268. FILE           *
  269. fopenb(fname, mode)
  270.     char           *fname;
  271.     char           *mode;
  272. {
  273.     FILE           *fopen();
  274.     char            modestr[16];
  275.  
  276.     sprintf(modestr, "%sb", mode);
  277.     return fopen(fname, modestr);
  278. }
  279.  
  280. /*
  281.  * raw() & cooked()
  282.  *
  283.  * These are routines for setting a given stream to raw or cooked mode on the
  284.  * Amiga. This is useful when you are using Lattice C to produce programs
  285.  * that want to read single characters with the "getch()" or "fgetc" call. 
  286.  *
  287.  * Written : 18-Jun-87 By Chuck McManis.
  288.  */
  289.  
  290. /*
  291.  * Function raw() - Convert the specified File Handle to 'raw' mode. This
  292.  * only works on TTY's and essentially keeps DOS from translating keys for
  293.  * you.
  294.  */
  295.  
  296. long
  297. raw(afh)
  298.     struct FileHandle *afh;
  299. {
  300.     struct MsgPort *mp;        /* The File Handle message port */
  301.     long            Arg[1], res;
  302.  
  303.     mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
  304.     Arg[0] = -1L;
  305.     res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);
  306.     if (res == 0) {
  307.     errno = ENXIO;
  308.     return (-1);
  309.     }
  310.     return (0);
  311. }
  312.  
  313. /*
  314.  * Function - cooked() this function returns the designate file pointer to
  315.  * it's normal, wait for a <CR> mode. This is exactly like raw() except that
  316.  * it sends a 0 to the console to make it back into a CON: from a RAW: 
  317.  */
  318.  
  319. long
  320. cooked(afh)
  321.     struct FileHandle *afh;
  322. {
  323.     struct MsgPort *mp;        /* The File Handle message port */
  324.     long            Arg[1], res;
  325.  
  326.     mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
  327.     Arg[0] = 0L;
  328.     res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);
  329.     if (res == 0) {
  330.     errno = ENXIO;
  331.     return (-1);
  332.     }
  333.     return (0);
  334. }
  335.  
  336. /*
  337.  * Code for this routine came from the following :
  338.  *
  339.  * ConPackets.c -  C. Scheppner, A. Finkel, P. Lindsay  CBM
  340.  *   DOS packet example
  341.  *   Requires 1.2
  342.  *
  343.  * which I found on Fish Disk 56.
  344.  */
  345.  
  346. /* initializes conWindow and conUnit (global vars) */
  347. long
  348. get_ConUnit(afh)
  349.     struct FileHandle *afh;
  350. {
  351.     struct MsgPort *mp;        /* The File Handle message port */
  352.     struct InfoData *id;
  353.     long            Arg[8], res;
  354.  
  355.     if (!IsInteractive((BPTR) afh)) {
  356.     errno = ENOTTY;
  357.     return (-1);
  358.     }
  359.     mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
  360.  
  361.     /* Alloc to insure longword alignment */
  362.     id = (struct InfoData *) AllocMem(sizeof(struct InfoData),
  363.                       MEMF_PUBLIC | MEMF_CLEAR);
  364.     if (!id) {
  365.     errno = ENOMEM;
  366.     return (-1);
  367.     }
  368.     Arg[0] = ((ULONG) id) >> 2;
  369.     res = SendPacket(mp, ACTION_DISK_INFO, Arg, 1);
  370.     conWindow = (struct Window *) id->id_VolumeNode;
  371.     conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit;
  372.     FreeMem(id, sizeof(struct InfoData));
  373.     if (res == 0) {
  374.     errno = ENXIO;
  375.     return (-1);
  376.     }
  377.     return (0);
  378. }
  379.  
  380. /*
  381.  * SendPacket() - written by Phil Lindsay, Carolyn Scheppner, and Andy
  382.  * Finkel. This function will send a packet of the given type to the Message
  383.  * Port supplied. 
  384.  */
  385.  
  386. long
  387. SendPacket(pid, action, args, nargs)
  388.     struct MsgPort *pid;    /* process indentifier ... (handlers message
  389.                  * port ) */
  390.     long            action,    /* packet type ... (what you want handler to
  391.                  * do )   */
  392.                     args[],    /* a pointer to a argument list */
  393.                     nargs;    /* number of arguments in list  */
  394. {
  395.     struct MsgPort *replyport;
  396.     struct StandardPacket *packet;
  397.  
  398.     long            count, *pargs, res1;
  399.  
  400.     replyport = (struct MsgPort *) CreatePort(NULL, 0);
  401.     if (!replyport)
  402.     return (0);
  403.  
  404.     /* Allocate space for a packet, make it public and clear it */
  405.     packet = (struct StandardPacket *)
  406.     AllocMem((long) sizeof(struct StandardPacket),
  407.          MEMF_PUBLIC | MEMF_CLEAR);
  408.     if (!packet) {
  409.     DeletePort(replyport);
  410.     return (0);
  411.     }
  412.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  413.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
  414.     packet->sp_Pkt.dp_Port = replyport;
  415.     packet->sp_Pkt.dp_Type = action;
  416.  
  417.     /* copy the args into the packet */
  418.     pargs = &(packet->sp_Pkt.dp_Arg1);    /* address of first argument */
  419.     for (count = 0; count < nargs; count++)
  420.     pargs[count] = args[count];
  421.  
  422.     PutMsg(pid, packet);    /* send packet */
  423.  
  424.     WaitPort(replyport);
  425.     GetMsg(replyport);
  426.  
  427.     res1 = packet->sp_Pkt.dp_Res1;
  428.  
  429.     FreeMem(packet, (long) sizeof(struct StandardPacket));
  430.     DeletePort(replyport);
  431.  
  432.     return (res1);
  433. }
  434.